﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using System.Net;
using System.IO;
using System.Threading;
using System.Windows.Threading;
using System.Text.RegularExpressions;



namespace FourDL {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 

    







    /*
     * 
     * 
     *
     */


    public partial class MainWindow : Window {

        string testUrl = "http://images.4chan.org/h/src/1315448934066.jpg";
        //string testPage = "http://boards.4chan.org/h/res/3112401";
        string testPage = "http://boards.4chan.org/h/res/3114181";

        public volatile bool THREADS_SHOULD_STOP = false;

        Thread TT;

        public MainWindow() {
            InitializeComponent();
        }

        public void log(string e) {
            DebugLog.Items.Add(e);
        }

        private void GetThread_Click(object sender, RoutedEventArgs e) {
            //Check for URL validity            
            string PAGE_URL = ThreadURL.Text;
            //URL = "http://boards.4chan.org/h/res/3114181";
            Regex UrlRegExp = new Regex("http://boards.4chan.org/[\\w+]/[a-z]+/[\\d]+$");
            Match sama = UrlRegExp.Match(PAGE_URL);
            if (sama.Success) {
                log("URL match! Proceeding to check Status...");
                //ThreadURL.Text = "";
            }
            else {
                log("URL FAIL");
                return;
            }
            // URL is OK, start thread to check / dl / everything
            DownloaderClass DownloadThread = new DownloaderClass(this, PAGE_URL);
            TT = new Thread(new ThreadStart(DownloadThread.DoStuff));
            TT.SetApartmentState(ApartmentState.STA);
            TT.Start();

            

        }

        private void Window_KeyDown(object sender, KeyEventArgs e) {
            //Ask to kill all ongoing threads
            //KillAllThreads();
            if (e.Key == Key.Escape) Application.Current.Shutdown();
        }


        private void TestButton_Click(object sender, RoutedEventArgs e) {
            string URL = ThreadURL.Text;
            //URL = "http://boards.4chan.org/h/res/3114181";
            return;

            TextReader tr = new StreamReader("uguu.txt");
            string html = tr.ReadToEnd();
            tr.Close();

            string picName;
            string folder;
        }

        private void ButtonCheckIfThreadAlive_Click(object sender, RoutedEventArgs e) {
            log(TT.IsAlive.ToString());
        }
        //private void ButtonCreateDirectory_Click(object sender, RoutedEventArgs e) {
        //    string path = "testdir";
        //    if (Directory.Exists(path)) log("onjo!");
        //    else {
        //        log("eio! luodaan");

        //        DirectoryInfo DirInfo = Directory.CreateDirectory(path);
        //    }
        //}
    }


    public class DownloaderClass {
        /*
         * Threaded class that handles downloads
         */
        private MainWindow PARENT;
        string PAGE_URL;
        string FOLDER;
        string FILE_RELATIVE_PATH;

        public volatile bool STOP_THREAD = true;

        int SLEEP_TIME = 30000; // 30 sec
        int AMOUNT_OF_DOWNLOADS = 1;

        //TODO: add regexps for errything


        public DownloaderClass(MainWindow ParentForm, string PageURL) {
            PARENT = ParentForm;
            PAGE_URL = PageURL;
            //PAGE_URL = PAGE_URL + "asd";

        }
        public void DoStuff() {
            CheckPage(PAGE_URL);
        }
        public void CheckForStopRequest() {
            if (STOP_THREAD) {
                Log("STOPPING!");
                //return? + volatile bool
            }
        }
        public void Log(string e) {
            PARENT.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => {
                PARENT.DebugLog.Items.Add(e);
            }));
        }


        private void CheckPage(string PAGE_URL) {
            // Check if thread is alive
            PARENT.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => {
                PARENT.ButtonNot.IsEnabled = false;
                //PARENT.ListViewActiveThreads.Items.Add("2");
            }));
            if (STOP_THREAD) {

                //return;
            }
            // Check page status
            HttpWebRequest PageRequest = (HttpWebRequest)WebRequest.Create(PAGE_URL);
            try {
                HttpWebResponse PageResponse = (HttpWebResponse)PageRequest.GetResponse();
                if (PageResponse.StatusCode == HttpStatusCode.OK) {
                    PARENT.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => {
                        PARENT.GetThread.IsEnabled = true;
                        Log("Got " + PageResponse.StatusCode.ToString());
                        Log("Downloading thread");
                    }));
                    DownloadPage(PAGE_URL);
                }
            }
            catch (WebException e) {
                //Fail, 404 or other shit
                PARENT.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => {
                    PARENT.GetThread.IsEnabled = true;
                    //TODO: handle errors
                    PARENT.log("Got an error. Handling errors.");
                    PARENT.log(e.ToString());
                }));

                //string code = ((HttpWebResponse)e.Response).StatusCode.ToString();
                //Log(code);
            }
        }

        private void DownloadPage(string PAGE_URL) {
            //Download the page html
            Regex foldernameregexp = new Regex("\\d+$");
            Match match = foldernameregexp.Match(PAGE_URL);
            if (match.Success) {
                FOLDER = match.ToString();
                Log("DL to folder: " + FOLDER);
            }
            else {
                FOLDER = "default";
            }

            //Folder exists?
            if (!Directory.Exists(FOLDER)) {
                DirectoryInfo DirInfo = Directory.CreateDirectory(FOLDER);
                Log("luotu kansio");
            }
            FOLDER += "/"; // Add the slash

            // Store the page html
            WebClient WebPage = new WebClient();
            Stream PageStream = WebPage.OpenRead(PAGE_URL);
            StreamReader data = new StreamReader(PageStream);
            string PageHTML;
            PageHTML = data.ReadToEnd(); //Contains page html
            PageStream.Close();

            PARENT.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => {
                PARENT.ListViewActiveThreads.Items.Add("added thread");
            }));

            DownloadFromHtml(PageHTML);
        }
        private void DownloadFromHtml(string PAGE_HTML) {
            List<String> PictureList = new List<String>();
            string previousPic = "";
            //Regex picRegexp = new Regex("\\d{5,}\\.\\w+");
            Regex picRegexp = new Regex("http://images.4chan.org/[\\w+]/src/[\\d]+.[\\w]+");

            Match m = picRegexp.Match(PAGE_HTML);
            while (m.Success) {
                if (previousPic != m.ToString()) {
                    PictureList.Add(m.ToString());
                }
                //Log(PictureList.Last().ToString());
                previousPic = m.ToString();
                m = m.NextMatch();
            }
            Log("Files to be downloaded");
            foreach (string filepath in PictureList) {
                Log(filepath);
            }
            foreach (string filepath in PictureList) {
                Regex name = new Regex("\\d{5,}.\\w+");
                Match PicMatch = name.Match(filepath);
                if (PicMatch.Success) {
                    //string picname = PicMatch.ToString();
                    DownloadSingle(filepath, PicMatch.ToString());
                }
            }

            //All downloaded (for now)
            WaitFor404();
        }
        private void DownloadSingle(string fileurl, string filename) {
            string relativePath = FOLDER + filename;
            //Check if file exists
            if (File.Exists(relativePath)) {
                Log(relativePath + " already exists, skipped");
                return;
            }

            WebClient PicDownloader = new WebClient();
            PicDownloader.DownloadFile(fileurl, FOLDER + filename);

            Log("Downloading: " + fileurl + " to folder " + FOLDER);
        }

        private void WaitFor404() {
            Log("Sleeping for " + SLEEP_TIME / 1000);
            Thread.Sleep(SLEEP_TIME);
            Log("Woke up");
        }

    }
}
